Skip to content

面向对象与原型 (Object Oriented & Prototype)

1. 原型链继承

javascript
function Animal(name) {
  this.name = name;
}

Animal.prototype.speek = function () {
  console.log(`${this.name} is speeking...`);
};

function Dog(name, age) {
  // 继承属性
  Animal.call(this, name);
  this.age = age;
}

// 继承方法:使用 Object.create 避免调用父类构造函数
Dog.prototype = Object.create(Animal.prototype);
Dog.prototype.constructor = Dog;

Dog.prototype.getAge = function () {
  return this.age;
};

const dog = new Dog('wangcai', 3);
dog.speek();

2. Class 类

ES6 语法糖写法。

javascript
class Person {
  constructor(name, age) {
    this.name = name || 'unknown';
    this.age = age || 0;
  }

  sayHello() {
    console.log(`Hi, I'm ${this.name}, age ${this.age}`);
  }
}

class Student extends Person {
  constructor(name, age, grade) {
    super(name, age);
    this.grade = grade || 1;
  }
  
  sayInfo() {
    this.sayHello();
    console.log(`Grade: ${this.grade}`);
  }
}

const s = new Student('Lisa', 20, 2);
s.sayInfo();

3. 手写 instanceof

instanceof 的核心原理是检查构造函数的 prototype 是否出现在对象的原型链上。

javascript
function myInstanceof(left, right) {
  // 获取对象的原型
  let proto = Object.getPrototypeOf(left);
  // 构造函数的 prototype
  const prototype = right.prototype;

  while (proto) {
    if (proto === prototype) return true;
    // 继续向上查找
    proto = Object.getPrototypeOf(proto);
  }
  return false;
}

4. 手写深拷贝 (Deep Clone)

javascript
export function deepClone(obj, hash = new WeakMap()) {
  if (obj === null || typeof obj !== 'object') return obj;

  // 处理循环引用
  if (hash.has(obj)) return hash.get(obj);

  let clone = Array.isArray(obj) ? [] : {};
  hash.set(obj, clone);

  for (let key in obj) {
    if (obj.hasOwnProperty(key)) {
      clone[key] = deepClone(obj[key], hash);
    }
  }

  return clone;
}

5. 查找对象深层属性

javascript
function findPropIn(propName, obj, visited = new Set()) {
  if (obj == undefined || typeof obj !== 'object') return;
  if (visited.has(obj)) return; // 避免循环引用死循环
  visited.add(obj);

  if (propName in obj) return obj[propName];

  for (let key of Object.keys(obj)) {
    let ret = findPropIn(propName, obj[key], visited);
    if (ret !== undefined) return ret;
  }
  return undefined;
}

MIT Licensed | Keep Learning.